package com.intco.ait.quotation.api.common.utils;

import com.intco.ait.quotation.api.common.enums.CharsetEnum;
import com.intco.ait.quotation.api.common.enums.ContentTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;

@Slf4j
public class HttpUtil {

    /**
     * 获取客户端IP
     *
     * @param request httpServletRequest
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    log.error("调用getIpAddr", e);
                }
                assert inet != null;
                ip = inet.getHostAddress();
            }
        }
        // 多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }

    /**
     * @param requestUrl     请求链接
     * @param parameterData  请求参数
     * @param charset        编码格式
     * @param reqContentType 请求内容格式
     * @param timeOut        单位毫秒
     */
    public static String doRequest(String requestUrl, String parameterData,
                                   RequestMethod requestMethod, CharsetEnum charset,
                                   ContentTypeEnum reqContentType, int timeOut) throws Exception {

        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        try {
            if (StringUtils.isEmpty(parameterData)) {
                parameterData = "";
            }
            URL httpUrl = new URL(requestUrl);
            URLConnection connection = httpUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) connection;

            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setRequestMethod(requestMethod.toString());
            httpUrlConnection.setRequestProperty("Content-Type", reqContentType.getDec() + ";charset=" + charset.getDec());
            if (!"get".equals(requestMethod.toString().toLowerCase())) {
                httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(parameterData.length()));
            }

            httpUrlConnection.setConnectTimeout(timeOut);
            httpUrlConnection.setReadTimeout(timeOut);

            outputStream = httpUrlConnection.getOutputStream();
            outputStreamWriter = new OutputStreamWriter(outputStream, charset.getDec());
            if (!"get".equals(requestMethod.toString().toLowerCase())) {
                outputStreamWriter.write(parameterData);
            }
            outputStreamWriter.flush();
            if (httpUrlConnection.getResponseCode() >= 300) {
                throw new Exception("HTTP Request is not success, Response code is " + httpUrlConnection.getResponseCode());
            }
            inputStream = httpUrlConnection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, charset.getDec());
            reader = new BufferedReader(inputStreamReader);
            String tempLine = null;
            while ((tempLine = reader.readLine()) != null) {
                resultBuffer.append(tempLine);
            }
        } catch (Exception e) {
            throw new Exception("调用HttpUtil.doRequest异常" + ExceptionUtils.getStackTrace(e));
        } finally {
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (reader != null) {
                reader.close();
            }
            if (inputStreamReader != null) {
                inputStreamReader.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return resultBuffer.toString();
    }

    /**
     * 默认XML方式请求，Post
     *
     * @param requestUrl  url
     * @param requestData data
     * @param timeout     Timeout in milliseconds.
     */
    public static String doPost(String requestUrl, String requestData, int timeout) throws Exception {
        return doRequest(requestUrl, requestData, RequestMethod.POST, CharsetEnum.UTF8, ContentTypeEnum.XML, timeout);
    }

    public static String doPost(String requestUrl, String requestData, ContentTypeEnum reqContentType, int timeout) throws Exception {
        return doRequest(requestUrl, requestData, RequestMethod.POST, CharsetEnum.UTF8, reqContentType, timeout);
    }

    /**
     * 默认XML方式请求，Get
     *
     * @param requestUrl url
     * @param timeout    超时时间
     */
    public static String doGet(String requestUrl, int timeout) throws Exception {
        return doRequest(requestUrl, null, RequestMethod.GET, CharsetEnum.UTF8, ContentTypeEnum.XML, timeout);
    }

    /**
     * 获取get 请求结果
     *
     * @param requestUrl url
     * @param timeout    超时时间
     */
    public static String getData(String requestUrl, int timeout) throws Exception {
        GetMethod getMethod = new GetMethod(requestUrl);
        getMethod.addRequestHeader("Content-Type", "text/html; charset=UTF-8");
        //最后生成一个HttpClient对象，并发出postMethod请求
        HttpClient httpClient = new HttpClient();
        //设置请求时间
        HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
        managerParams.setConnectionTimeout(timeout);
        String rstString = "";
        try {
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode == 200) {
                rstString = getMethod.getResponseBodyAsString();
            }
        } catch (Exception e) {
            throw new Exception("调用HttpUtils.getData异常", e);
        } finally {
            getMethod.releaseConnection();
        }
        return rstString;
    }

    /**
     * 提交数据
     *
     * @param requestUrl  url
     * @param requestData data
     * @param charset     charset
     * @param contentType contentType
     * @param timeout     timeout
     */
    public static String doPost(String requestUrl, String requestData,
                                CharsetEnum charset, ContentTypeEnum contentType, int timeout) throws IOException {
        PostMethod postMethod = new PostMethod(requestUrl);
        postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset.getDec());
        // 把请求数据添加到PostMethod中
        byte[] b = requestData.getBytes(charset.getDec());
        InputStream is = new ByteArrayInputStream(b, 0, b.length);
        RequestEntity re = new InputStreamRequestEntity(is, b.length, contentType.getDec());
        postMethod.setRequestEntity(re);
        //最后生成一个HttpClient对象，并发出postMethod请求
        HttpClient httpClient = new HttpClient();
        //设置请求时间
        HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
        managerParams.setConnectionTimeout(timeout);

        String rstString = "";
        try {
            int statusCode = httpClient.executeMethod(postMethod);
            if (statusCode == 200) {
                rstString = postMethod.getResponseBodyAsString();
            }
        } catch (Exception e) {
            log.error("调用doPost异常", e);
        } finally {
            postMethod.releaseConnection();
        }
        return rstString;
    }
}